import { once } from './on';
const readyStates = Object.create(null) as {
	loaded: boolean;
	complete: boolean;
	[key: string]: boolean;
};
readyStates.loaded = readyStates.complete = true;

let ready = readyStates[document.readyState];

let readyQueue: Array<(doc: Document) => void> = [];
let processing = false;

function processQueue(): void {
	if (processing) {
		return;
	}
	processing = true;

	for (let i = 0; i < readyQueue.length; i++) {
		readyQueue[i](document);
	}
	readyQueue = [];
	processing = false;
}

function ready_fun() {
	if (ready) {
		return;
	}
	ready = true;
	processQueue();
}

if (!ready) {
	if (document.addEventListener) {
		if (document.readyState === 'complete' || (document.readyState !== 'loading' && !(document.documentElement as any).doScroll)) {
			// DOMContentLoaded has emited
			ready_fun();
		} else {
			once(document, 'DOMContentLoaded', () => {
				ready_fun();
			});
		}
	} else {
		// IE8 兼容代码
		const fun = () => {
			try {
				(document.documentElement as unknown as { doScroll(dir: string): void }).doScroll('left');
				ready_fun();
			} catch (error) {
				setTimeout(fun, 0);
				return;
			}
		};
		fun();
	}
}

export function dom_ready(callback: (...args: any[]) => void): void {
	readyQueue.push(callback);
	if (ready) {
		processQueue();
	}
}

export default function() {
	return new Promise<void>((resolve, reject) => {
		dom_ready(() => {
			resolve();
		});
	});
}
